package org.web.base.domain.helper;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class ListHelper {



    /**
     * 日期格式化器，线程安全使用时需注意，如单线程使用可直接用
     */
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 将对象列表转换为 List<LinkedList<String>>，每个 LinkedList 代表一行，
     * 按照 attributeList 指定的属性顺序，调用 getter 方法获取属性值。
     *
     * @param <T> 泛型对象类型
     * @param dataList 对象数据列表
     * @param clazz 对象的 Class 类型
     * @param attributeList 属性名列表（不带 get/is 前缀，决定输出顺序）
     * @return 每行一个对象的数据，按属性顺序拼接的字符串链表
     */
    public static <T> List<LinkedList<String>> convertObjectList2StringList(List<T> dataList, List<String> attributeList) {

        List<LinkedList<String>> result = new ArrayList<>();
        if (dataList == null || dataList.isEmpty() || attributeList == null || attributeList.isEmpty()) {
            return result;
        }

        // 每个实际类型缓存一个 getterMap（避免 item 类型不一致的问题）
        Map<Class<?>, Map<String, Method>> classGetterCache = new HashMap<>();

        for (T item : dataList) {
            LinkedList<String> row = new LinkedList<>();
            Class<?> realClass = item.getClass();
            Map<String, Method> getterMap = classGetterCache.computeIfAbsent(realClass, cls -> {
                Map<String, Method> map = new HashMap<>();
                for (String attr : attributeList) {
                    String capitalized = Character.toUpperCase(attr.charAt(0)) + attr.substring(1);
                    String getterName = "get" + capitalized;
                    String isGetterName = "is" + capitalized;
                    try {
                        Method method = cls.getMethod(getterName);
                        map.put(attr, method);
                    } catch (NoSuchMethodException e1) {
                        try {
                            Method method = cls.getMethod(isGetterName);
                            map.put(attr, method);
                        } catch (NoSuchMethodException e2) {
                            // getter 不存在，跳过
                        }
                    }
                }
                return map;
            });

            for (String attr : attributeList) {
                Object value = null;
                Method getter = getterMap.get(attr);
                if (getter != null) {
                    try {
                        value = getter.invoke(item);
                    } catch (Exception e) {
                        // 调用失败，value 为 null
                    }
                }

                if (value == null) {
                    row.add(null);
                } else if (value instanceof Date) {
                    row.add(DATE_FORMAT.format((Date) value));
                } else {
                    row.add(String.valueOf(value));
                }
            }

            result.add(row);
        }

        return result;
    }



    /**
     * 将List转换为String，使用指定分隔符连接
     *
     * @param list      要转换的List
     * @param delimiter 分隔符
     * @return 连接后的字符串
     */
    public static <T> String listToString(List<T> list, String delimiter) {
        if (list == null || list.isEmpty()) {
            return "";
        }
        return list.stream()
                .map(item -> item != null ? item.toString() : "")
                .collect(Collectors.joining(delimiter));
    }

    /**
     * 将重复元素（基于 toString）拼接为字符串
     */
    public static <T> String findDuplicatesByToString(List<T> list, String delimiter) {
        List<T> duplicates = findDuplicates(list);
        return listToString(duplicates, delimiter);
    }

    /**
     * 将String转换为List（仅适用于String类型）
     *
     * @param str       要转换的字符串
     * @param delimiter 分隔符
     * @return 拆分后的List
     */
    public static List<String> stringToList(String str, String delimiter) {
        if (str == null || str.trim().isEmpty()) {
            return Collections.emptyList();
        }
        return Arrays.stream(str.split(delimiter))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .collect(Collectors.toList());
    }

    // ========== 通用重复项查找方法 ==========

    /**
     * 统计列表中每个元素的出现次数
     *
     * @param list 元素列表
     * @return 元素到出现次数的映射
     */
    public static <T> Map<T, Integer> countOccurrences(List<T> list) {
        Map<T, Integer> countMap = new HashMap<>();
        for (T item : list) {
            countMap.put(item, countMap.getOrDefault(item, 0) + 1);
        }
        return countMap;
    }

    /**
     * 从统计映射中收集重复元素
     *
     * @param countMap 元素统计映射
     * @return 重复元素列表
     */
    public static <T> List<T> collectDuplicates(Map<T, Integer> countMap) {
        return countMap.entrySet().stream()
                .filter(entry -> entry.getValue() > 1)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    /**
     * 查找列表中的重复元素（组合方法）
     *
     * @param list 元素列表
     * @return 重复元素列表
     */
    public static <T> List<T> findDuplicates(List<T> list) {
        return collectDuplicates(countOccurrences(list));
    }

    // ========== 针对Integer的专用方法 ==========

    /**
     * 将数字字符串转换为Integer列表
     *
     * @param str       数字字符串（如"1,2,3"）
     * @param delimiter 分隔符
     * @return Integer列表
     */
    public static List<Integer> stringToIntList(String str, String delimiter) {
        if (str == null || str.trim().isEmpty()) {
            return Collections.emptyList();
        }
        return Arrays.stream(str.split(delimiter))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .map(Integer::parseInt)
                .collect(Collectors.toList());
    }
}